home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / dbwrendr.zip / SOURCE / HIT.C < prev    next >
Text File  |  1989-04-17  |  11KB  |  387 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *                    Copyright (c) 1987, David B. Wecker               *
  4.  *                            All Rights Reserved                       *
  5.  *                                                                      *
  6.  * This file is part of DBW_Render                                      *
  7.  *                                                                      *
  8.  * DBW_Render is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts               *
  10.  * responsibility to anyone for the consequences of using it or for     *
  11.  * whether it serves any particular purpose or works at all, unless     *
  12.  * he says so in writing. Refer to the DBW_Render General Public        *
  13.  * License for full details.                                            *
  14.  *                                                                      *
  15.  * Everyone is granted permission to copy, modify and redistribute      *
  16.  * DBW_Render, but only under the conditions described in the           *
  17.  * DBW_Render General Public License. A copy of this license is         *
  18.  * supposed to have been given to you along with DBW_Render so you      *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named COPYING. Among other things, the copyright notice and this     *
  21.  * notice must be preserved on all copies.                              *
  22.  ************************************************************************
  23.  *                                                                      *
  24.  * Authors:                                                             *
  25.  *        DBW - David B. Wecker                                         *
  26.  *                                                                      *
  27.  * Versions:                                                            *
  28.  *        V1.0 870125 DBW  - First released version                     *
  29.  *                                                                      *
  30.  ************************************************************************/
  31.  
  32. #define MODULE_HIT
  33. #include "ray.h"
  34.  
  35. void findnormal(np,p,n)
  36. node    *np;
  37. vector  p,
  38. n;
  39. {
  40.      vector ripple,fuzzy,bevelx,bevely,bevelz,tmp;
  41.      float t;
  42.      int w,j,it;
  43.  
  44.      switch (np->kind) 
  45.      {
  46.      case SPHERE   :
  47.           SPHERENORMAL(sptr(np)->center,p,n);
  48.           break;
  49.      case TRIANGLE :
  50.           PLANENORMAL(tptr(np)->ve,tptr(np)->vp,n);
  51.           break;
  52.      case QUAD     :
  53.           PLANENORMAL(qptr(np)->ve,qptr(np)->vp,n);
  54.           break;
  55.      case RING     :
  56.           PLANENORMAL(rptr(np)->ve,rptr(np)->vp,n);
  57.           break;
  58.      }
  59.  
  60.      if (np->attr.tex != 0) 
  61.      { /* don't bother checking if there's no texture */
  62.           if (np->attr.tex == 4) 
  63.           { /* fiddle with normal for all ripples */
  64.                for (w = 0; w < numwaves; w++) 
  65.                {
  66.                     calcripple(p,w,ripple);  /* calculate the wave perturbation */
  67.                     vecsum(ripple,n,n);  /* add ripple bend to normal */
  68.                }
  69.                normalize(n);  /* make sure it's a unit vector after all that */
  70.           }
  71.  
  72.           /* fiddle with normal for one ripple */
  73.           else if (np->attr.tex >= 10 && np->attr.tex <= 19) 
  74.           {
  75.                calcripple(p,np->attr.tex - 10,ripple);  /* calc wave perturbation */
  76.                vecsum(ripple,n,n);  /* add ripple bend to normal */
  77.                normalize(n);  /* make sure it's still a unit vector */
  78.           }
  79.  
  80.           /* check for rough pebbly surface */
  81.           else if (np->attr.tex >= 90 && np->attr.tex <= 99) 
  82.           {
  83.                j = np->attr.tex - 90;  /* select the desired pebble finish */
  84.                vecscale(pebble[j].zoom,p,tmp);
  85.                fuzzy[0] = turbulence(tmp);
  86.                vecscale(1.5,tmp,tmp);
  87.                fuzzy[1] = turbulence(tmp);
  88.                vecscale(1.5,tmp,tmp);
  89.                fuzzy[2] = turbulence(tmp);
  90.                if (fuzzy[0] > 0.7)
  91.                     fuzzy[0] = 0.7;
  92.                if (fuzzy[1] > 0.7)
  93.                     fuzzy[1] = 0.7;
  94.                if (fuzzy[2] > 0.7)
  95.                     fuzzy[2] = 0.7;
  96.                if (rnd() < 0.5)
  97.                     fuzzy[0] = -fuzzy[0];
  98.                if (rnd() < 0.5)
  99.                     fuzzy[1] = -fuzzy[1];
  100.                if (rnd() < 0.5)
  101.                     fuzzy[2] = -fuzzy[2];
  102.                vecscale(pebble[j].scale,fuzzy,fuzzy);
  103.                vecsum(n,fuzzy,n);
  104.                normalize(n);
  105.           }
  106.      }
  107.  
  108.      /*---------------------------------------------------------------------*/
  109.      /* Add any general normal perturbations                                */
  110.  
  111.      if (np->attr.fuz > 0.0) 
  112.      {
  113.           /* Perturb the normal randomly to produce fuzzy surfaces */
  114.           fuzzy[0] = rnd();  /* 0..1 */
  115.           fuzzy[1] = rnd();
  116.           fuzzy[2] = rnd();
  117.           if (rnd() < 0.5)
  118.                fuzzy[0] = -fuzzy[0];
  119.           if (rnd() < 0.5)
  120.                fuzzy[1] = -fuzzy[1];
  121.           if (rnd() < 0.5)
  122.                fuzzy[2] = -fuzzy[2];
  123.  
  124.           /* 'fuzzy' is now approximately a random unit vector */
  125.           vecscale(rnd() * np->attr.fuz,fuzzy,fuzzy);
  126.           vecsum(fuzzy,n,n); /* vector addition of fuzz compunent to true normal */
  127.           normalize(n);  /* Make sure it's still a unit vector */
  128.      }
  129. }
  130.  
  131. int hitcylinder(cp,eye,d,p,t)
  132. cylinder *cp;  /* the cylinder      */
  133. vector eye;    /* source ray origin */
  134. vector d;      /* source ray        */
  135. vector p;
  136. float  *t;
  137. {
  138.      float aa,bb,cc,radical,a2,b2,c2,dist1,dist2;
  139.      vector otop,oeye,p1,p2,opoint1,opoint2;
  140.  
  141.      /*
  142.       *   translate bottom of cylinder to 0,0,0
  143.       *   get translated eyepoint and cylinder top
  144.       */
  145.  
  146.      VECSUB(eye,    cp->bottom, oeye);
  147.      VECSUB(cp->top,cp->bottom, otop);  /* ? */
  148.  
  149.  
  150.      a2 = cp->a*cp->a;
  151.      b2 = cp->b*cp->b;
  152.      c2 = cp->c*cp->c;
  153.  
  154.      if (a2 < SMALL) return( FALSE );
  155.      if (b2 < SMALL) return( FALSE );
  156.      if (c2 < SMALL) return( FALSE );
  157.  
  158.  
  159.      aa  = d[0]*d[0] / a2;
  160.      aa += d[2]*d[2] / b2;
  161.      aa -= d[1]*d[1] / c2;
  162.  
  163.      bb  = d[0]*oeye[0] / a2;
  164.      bb += d[2]*oeye[2] / b2;
  165.      bb -= d[1]*oeye[1] / c2;
  166.  
  167.      cc  = oeye[0]*oeye[0] / a2;
  168.      cc += oeye[2]*oeye[2] / b2;
  169.      cc -= oeye[1]*oeye[1] / c2;
  170.  
  171. /*   
  172.  *   descriminate < 0,  ray misses cylinder
  173.  *   descriminate == 0, ray grazes cylinder
  174.  */
  175.  
  176.      if ((radical = (bb*bb) - (4.0*aa*cc)) < 0.0)
  177.           return( FALSE );
  178.  
  179.      radical = sqrt(radical);
  180.  
  181.      aa = 2.0 * aa;
  182.  
  183.      if ( aa < SMALL ) 
  184.           return( FALSE );  
  185.  
  186.      /* the roots of the quadratic */
  187.  
  188.      dist1 = (-bb + radical) / aa;
  189.      dist2 = (-bb - radical) / aa;
  190.  
  191.  
  192.      VECSCALE(dist1,d,p1);
  193.      VECSUM(p1,oeye,p1);
  194.      VECSCALE(dist2,d,p2);
  195.      VECSUM(p2,oeye,p2);
  196.      VECSUB(oeye,p1,opoint1);
  197.      VECSUB(oeye,p2,opoint2);
  198.      dist1 = NORM(opoint1);
  199.      dist2 = NORM(opoint2);
  200.  
  201.      if (dist1 < dist2) 
  202.      { 
  203.           VECCOPY(p1,p); 
  204.           *t = dist1; 
  205.      }
  206.      else
  207.      { 
  208.           VECCOPY(p2,p); 
  209.           *t = dist2; 
  210.      }
  211.  
  212.      return( TRUE );
  213. }
  214.  
  215. int hitsphere(center,radius,eye,d,p,t)
  216. vector  center;     /* where it is  */
  217. vector  eye;        /* where we are */
  218. vector  d;
  219. vector  p;
  220. float   radius;     /* how big it is */
  221. float   *t;
  222. {
  223.      float   r_r,d_r,t2,radical;
  224.      vector  r;
  225.  
  226.      VECSUB(center,eye,r);
  227.      r_r = DOT(r,r);
  228.      d_r = DOT(d,r);
  229.  
  230.      if ((radical = (d_r*d_r) + (radius*radius) - r_r) < 0.0) 
  231.           return( FALSE );
  232.  
  233.      radical = sqrt(radical);
  234.  
  235.      if (d_r < radical) 
  236.      { 
  237.           *t = d_r + radical; 
  238.           t2 = d_r - radical; 
  239.      }
  240.      else
  241.      { 
  242.           *t = d_r - radical; 
  243.           t2 = d_r + radical; 
  244.      }
  245.  
  246.      if (fabs(*t) < SMALL) 
  247.           *t = t2;
  248.  
  249.      if (*t <= 0) 
  250.